package server.bootstrap;

import java.util.EnumSet;

import javax.servlet.DispatcherType;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.CrossOriginFilter;

import server.customers.CustomersServlet;
import server.database.DatabaseService;
import server.feedbacks.FeedbackServlet;
import server.feedbacks.FeedbacksReportServlet;
import server.orders.OrdersDashboardServlet;
import server.orders.OrdersServlet;
import server.resources.AreasServlet;
import server.resources.CranesServlet;
import server.resources.ProductsServlet;
import server.resources.TrucksServlet;
import server.users.AuthorizationServlet;
import server.users.UsersServlet;
import services.ServiceException;

public class YtongServer
{

	private static Logger log = Logger.getLogger(YtongServer.class);
	public static final int MAIN_PORT = 8080;

	public YtongServer()
	{
		PropertyConfigurator.configure("conf/log4j.properties");
		log.info("StowagePlanner server starting");

		Server server = new Server(MAIN_PORT);

		ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
		context.setContextPath("/");
		FilterHolder filter = new FilterHolder(new CrossOriginFilter());
		filter.setInitParameter("allowedMethods", "GET,POST");
		context.addFilter(filter, "/*", EnumSet.of(DispatcherType.REQUEST));

		server.setHandler(context);

		configureServlets(context);
		try
		{
			InitServices();
		}
		catch (ServiceException initException)
		{
			log.error("Initializing services failed: " + initException.getMessage());
			return;
		}

		try
		{
			log.info("Starting server");
			server.start();
		}
		catch (Exception e)
		{
			log.error("Starting server failed: " + e.getMessage());
			DatabaseService.getInstance().closeDatabase();
			return;
		}

		try
		{
			server.join();
		}
		catch (InterruptedException interruptedException)
		{
			log.error("Connecting to server failed: " + interruptedException.getMessage());
			try
			{
				server.stop();
			}
			catch (Exception serverException)
			{
				log.error("Stopping server failed: " + serverException.getMessage());
			}

			DatabaseService.getInstance().closeDatabase();
			return;
		}
	}

	private void InitServices() throws ServiceException
	{
		DatabaseService.initService();
	}

	private void configureServlets(ServletContextHandler context)
	{
		context.addServlet(new ServletHolder(new UsersServlet()), UsersServlet.PATH);
		context.addServlet(new ServletHolder(new AuthorizationServlet()), AuthorizationServlet.PATH);
		context.addServlet(new ServletHolder(new FeedbackServlet()), FeedbackServlet.PATH);
		context.addServlet(new ServletHolder(new CustomersServlet()), CustomersServlet.PATH);
		context.addServlet(new ServletHolder(new TrucksServlet()), TrucksServlet.PATH);
		context.addServlet(new ServletHolder(new CranesServlet()), CranesServlet.PATH);
		context.addServlet(new ServletHolder(new ProductsServlet()), ProductsServlet.PATH);
		context.addServlet(new ServletHolder(new AreasServlet()), AreasServlet.PATH);
		context.addServlet(new ServletHolder(new OrdersServlet()), OrdersServlet.PATH);

		context.addServlet(new ServletHolder(new OrdersDashboardServlet()), OrdersDashboardServlet.PATH);
		context.addServlet(new ServletHolder(new FeedbacksReportServlet()), FeedbacksReportServlet.PATH);
	}

	public static void main(String[] args)
	{
		new YtongServer();
	}
}
